import {
  app,
  BrowserWindow,
  clipboard,
  dialog,
  DownloadItem,
  ipcMain,
  IpcMainEvent,
  IpcMainInvokeEvent,
  Notification,
  session,
  shell,
} from "electron";
import fs from "fs";
import { selectFilePath } from "../utils/common.ts";
import path from "node:path";
import { IDownloadFileParams, IDownloadFileRes } from "../types/file.ts";
import { UpdateMessageFilePath } from "../db/servers/message.ts";

const downloadTasks = new Map<string, DownloadItem>();
export function FileEvent() {
  // 获取默认保存路径
  ipcMain.handle("getDefaultDownLoadPath", (_event: IpcMainInvokeEvent) => {
    return app.getPath("downloads");
  });

  // 选择文件保存路径
  ipcMain.handle("selectFilePath", async (_event, fileName: string, fileType: string) => {
    return await selectFilePath(fileName, fileType);
  });
  // 文件另存为
  ipcMain.handle("saveFileAs", async (_event: IpcMainInvokeEvent, sourceFilePath: string) => {
    try {
      // 检查源文件是否存在
      if (!fs.existsSync(sourceFilePath)) {
        console.error("文件不存在:", sourceFilePath);
        return { success: false, error: "文件不存在" };
      }
      const fileName = path.basename(sourceFilePath);
      const { canceled, filePath: targetFilePath } = await dialog.showSaveDialog({
        title: "另存为",
        defaultPath: fileName, //
        buttonLabel: "保存",
        properties: ["createDirectory"],
      });
      if (canceled || !targetFilePath) return false;
      fs.copyFileSync(sourceFilePath, targetFilePath);
      return true;
    } catch (error: any) {
      console.error("另存为失败:", error);
      return false;
    }
  });

  // 打开文件
  ipcMain.on("openFileByPath", async (_event: IpcMainEvent, filePath: string) => {
    try {
      await shell.openPath(filePath);
    } catch (error) {
      console.error("打开文件失败:", error);
    }
  });

  // 打开文件所在目录
  ipcMain.handle("openFileDirectoryByPath", async (_event: IpcMainInvokeEvent, filePath: string) => {
    try {
      if (!fs.existsSync(filePath)) {
        console.error("文件不存在:", filePath);
        return false;
      }
      shell.showItemInFolder(path.resolve(filePath));
      return true;
    } catch (error) {
      console.error("打开文件失败:", error);
      return false;
    }
  });

  // 复制文件
  ipcMain.handle("copyFileByPath", async (_event: IpcMainInvokeEvent, filePath: string) => {
    try {
      if (!fs.existsSync(filePath)) {
        console.error("文件不存在:", filePath);
        return false;
      }
      console.log("准备复制", filePath);
      const fileContent = fs.readFileSync(filePath);
      const fileName = path.basename(filePath);
      clipboard.writeBuffer("application/octet-stream", fileContent);
      const filePathBuffer = Buffer.from(fileName + "\0", "utf16le");
      clipboard.writeBuffer("FileNameW", filePathBuffer);
      return true;
    } catch (error) {
      console.error("文件复制出错:", filePath, error);
      return false;
    }
  });

  // 下载文件 返回进度
  ipcMain.on("downloadFile", async (event: IpcMainEvent, params: IDownloadFileParams): Promise<IDownloadFileRes> => {
    const win = BrowserWindow.fromWebContents(event.sender);

    if (!win) throw new Error("窗口不存在");
    const ses = session.defaultSession;
    ses.once("will-download", (_event, item: DownloadItem, _webContents) => {
      const totalBytes: number = item.getTotalBytes();
      const fileSavePath = path.join(params.savePath, item.getFilename());
      item.setSavePath(fileSavePath);
      downloadTasks.set(params.taskId, item);
      // 下载进度监听
      item.on("updated", (_event, state: string) => {
        if (!downloadTasks.get(params.taskId)) return;
        if (state === "progressing") {
          const receivedBytes: number = item.getReceivedBytes();
          const progress: number = totalBytes > 0 ? (receivedBytes / totalBytes) * 100 : 0;
          win.webContents.send("downloadProgress", {
            taskId: params.taskId,
            progress: parseFloat(progress.toFixed(2)),
            received: receivedBytes,
            total: totalBytes,
          });
        }
      });
      // 下载完成或失败
      item.once("done", async (_event, state: string) => {
        if (state === "completed") {
          new Notification({
            title: `文件已经保存到了 ${fileSavePath}`,
          }).show();
          UpdateMessageFilePath(params.userId, params.taskId, fileSavePath);
        }
        win.webContents.send("downloadDone", {
          taskId: params.taskId,
          fileSavePath,
          state,
        });
        downloadTasks.delete(params.taskId);
      });
    });

    // 触发下载
    win.webContents.downloadURL(params.fileUrl);
    return { progress: 100, done: true };
  });

  // 暂停下载
  ipcMain.on("pauseDownload", (event: IpcMainEvent, taskId: string) => {
    const item = downloadTasks.get(taskId);
    if (item && !item.isPaused()) {
      item.pause();
      const win = BrowserWindow.fromWebContents(event.sender);
      if (win) {
        win.webContents.send("downloadPaused", {
          taskId,
          received: item.getReceivedBytes(),
          total: item.getTotalBytes(),
        });
      }
    }
  });

  // 恢复下载
  ipcMain.on("resumeDownload", (event: IpcMainEvent, taskId: string) => {
    const item = downloadTasks.get(taskId);
    if (item && item.isPaused()) {
      item.resume();
      const win = BrowserWindow.fromWebContents(event.sender);
      if (win) {
        win.webContents.send("downloadResumed", { taskId });
      }
    }
  });

  // 取消下载
  ipcMain.on("cancelDownload", (_event: IpcMainEvent, taskId: string) => {
    const item = downloadTasks.get(taskId);
    if (item) {
      item.removeAllListeners("updated");
      item.removeAllListeners("done");
      item.cancel();
      downloadTasks.delete(taskId);
    }
  });
}
